// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
const db = cloud.database()
const _ = db.command
const $ = db.command.aggregate

async function searchOrderList(searchText, searchData) {
  const res = await db.collection('tb_order').aggregate()
    .match(searchData)
    .lookup({
      from: 'tb_stadium',
      let: {
        stadium_id: $.substrBytes(['$appointment_id', 0, $.indexOfBytes(['$appointment_id', '-'])])
      },
      pipeline: $.pipeline()
        .match(_.expr($.and([
          $.eq(['$_id', '$$stadium_id'])
        ])))
        .project({ stadium_name: 1, stadium_phone: 1, stadium_addr: 1 })
        .done()
      ,
      as: 'stadium'
    })
    .lookup({
      from: 'tb_user_info',
      localField: 'user_id',
      foreignField: '_id',
      as: 'user'
    })
    .lookup({
      from: 'tb_court',
      localField: 'sku_list.court_id',
      foreignField: '_id',
      as: 'courts'
    })
    .project({
      user_id: 1, appointment_id: 1, order_state: 1, modified_time: 1, created_time: 1,
      sku_list: 1, price_list: 1, payment_price: 1, payment_time: 1, courts: 1, stadium: 1,
      stadium_name: $.let({
        vars: {
          stadium: $.arrayElemAt(['$stadium', 0])
        },
        in: '$$stadium.stadium_name'
      }),
      real_name: $.arrayElemAt(['$user.real_name', 0]),
    })
    .match(
      _.or([
        { stadium_name: new RegExp(searchText, 'i') },
        { username: new RegExp(searchText, 'i') },
      ])
    )
    .sort({ modified_time: -1 })
    .limit(200)
    .end();
  return res.list;
}

// 查找订单、核销状态、订单变动
async function findOne(order_id) {
  const res1 = await db.collection('tb_order').aggregate()
    .match({ _id: order_id })
    .lookup({
      from: 'tb_stadium',
      let: {
        stadium_id: $.substrBytes(['$appointment_id', 0, $.indexOfBytes(['$appointment_id', '-'])])
      },
      pipeline: $.pipeline()
        .match(_.expr($.and([
          $.eq(['$_id', '$$stadium_id'])
        ])))
        .project({ stadium_name: 1, stadium_phone: 1, stadium_addr: 1 })
        .done()
      ,
      as: 'stadium'
    })
    .lookup({
      from: 'tb_user_info',
      localField: 'user_id',
      foreignField: '_id',
      as: 'user'
    })
    .lookup({
      from: 'tb_court',
      localField: 'sku_list.court_id',
      foreignField: '_id',
      as: 'courts'
    })
    .project({
      user_id: 1, appointment_id: 1, order_state: 1, modified_time: 1, created_time: 1,
      sku_list: 1, price_list: 1, payment_price: 1, payment_time: 1, courts: 1, stadium: 1,
      stadium_name: $.let({
        vars: {
          stadium: $.arrayElemAt(['$stadium', 0])
        },
        in: '$$stadium.stadium_name'
      }),
      user: $.arrayElemAt(['$user', 0]),
    })
    .sort({ modified_time: -1 })
    .limit(200)
    .end();
  const res2 = await db.collection('tb_coupon').aggregate()
    .match({ order_id })
    .limit(200)
    .end()
  const res3 = await db.collection('tb_order_change').aggregate()
    .match({ order_id })
    .sort({ modified_time: 1 })
    .limit(10)
    .end()
  return { order: res1.list[0], coupon_list: res2.list, order_change_list: res3.list };
}

// 生成订单、订单变动
async function addOrder(user_id, appointment_id, sku_list) {
  const stadium_id = appointment_id.substring(0, appointment_id.indexOf('-'));
  // 计算最新金额
  const court_map = new Map();
  (await db.collection('tb_court').aggregate()
    .match({ stadium_id })
    .limit(200)
    .end()
  ).list.forEach(o => court_map.set(o._id, o.court_price));
  const price_list = sku_list.map(o => court_map.get(o.court_id));
  // 生成订单
  const ts = new Date().getTime();
  const payment_price = price_list.reduce((tot, cur) => tot + cur, 0);
  const order_id = (
    await db.collection('tb_order').add({
      data: {
        user_id,
        appointment_id,
        order_state: 0,
        modified_time: ts,
        created_time: ts,
        sku_list,
        price_list,
        payment_price,
        modified_user_id: user_id,
      }
    })
  )._id;
  return { errMsg: '', payment_price, order_id };
}

async function updateOrder(order_id, updData) {
  updData.modified_time = new Date().getTime();
  return await db.collection('tb_order').doc(order_id)
    .update({ data: updData })
}

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const openid = wxContext.OPENID;

  if (event.funcName == 'insert') {
    return await addOrder(openid, event.appointment_id, event.sku_list);
  } else if (event.funcName == 'query') {
    if (event.searchData.user_id) event.searchData.user_id = openid;
    return await searchOrderList(event.searchText, event.searchData);
  } else if (event.funcName == 'update') {
    return await updateOrder(event.order_id, event.updData);
  } else if (event.funcName == 'queryOne') {
    return await findOne(event.order_id)
  }

  return {
    event,
    // appid: wxContext.APPID,
    // unionid: wxContext.UNIONID,
  }
}